﻿//-----------------------------------------------------------------------
// <copyright file="RuleEngine.cs" company="tuliprules.org">
//     Copyright (c) 2010 tuplelister, tuliprules.org.
// </copyright>
// <summary>This is the RuleEngine class.</summary>
//-----------------------------------------------------------------------

namespace Tulip.Rules
{
    using System;

    /// <summary>
    /// The RuleEngine class provides a concrete implementation of the 
    /// IRuleEngine interface and additional interfaces in oder to provide
    /// access to productions systems.
    /// </summary>
    /// <remarks>By default, the RuleEngine class will select the 'default' 
    /// implementations of the model tranform, executor factory, working 
    /// memory and agenda.</remarks>
    public class RuleEngine : IRuleEngine, IContinuousQuery, IProductionSystem
    {
        /// <summary>
        /// The ruleSet being processed by this session of the rule engine.
        /// </summary>
        private readonly RuleSet currentRuleSet;

        /// <summary>
        /// Initializes a new instance of the RuleEngine class.
        /// </summary>
        /// <param name="ruleSet">
        /// A rule set that will be processed by this session of the rule engine.
        /// </param>
        public RuleEngine(RuleSet ruleSet)
        {
            if (ruleSet == null)
            {
                throw new ArgumentNullException("ruleSet");
            }

            this.currentRuleSet = ruleSet;
        }

        /// <summary>
        /// Invokes registered handlers that will be invoked when the engine halts.
        /// </summary>
        private event RuleEngineHaltHandler OnHalt;

        /// <summary>
        /// Gets the ruleSet being processed by this session of the rule engine.
        /// </summary>
        /// <value>The ruleSet being processed by this session of the rule engine.</value>
        public RuleSet RuleSet
        {
            get
            {
                return this.currentRuleSet;
            }
        }

        /// <summary>
        /// Gets the current working memory of the production system.
        /// </summary>
        /// <remarks>The working memory stores asserted tuples and provides functionality for asserting, retracting and modifying tuples.</remarks>
        /// <value>The current working memory of the production system.</value>
        public IWorkingMemory WorkingMemory
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        /// <summary>
        /// Gets the agenda currently being used by the rule engine.
        /// </summary>
        /// <remarks>The agenda represents the current resolved conflict set and can be used to inspect or clear activations.</remarks>
        /// <value>The agenda currently being used by the rule engine.</value>
        public IAgenda Agenda
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        /// <summary>
        /// Executes a rule set using an executor.
        /// </summary>
        /// <remarks>The RuleEngine class uses a service locator to locate the correct model transform, executor factory, working memory and agenda implementations for a given rule set.</remarks>
        public void Execute()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Runs a session of the rule engine in 'continuous query' mode.
        /// </summary>
        /// <remarks>In 'continuous query' mode, the rule engine  ndoes not halt until the 'halt' method is called or the rules invoke a Halt operation internally.  New factTypes can be asserted continuously.</remarks>
        public void Run()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Halts a currently-running session of the rule engine.
        /// </summary>
        /// <remarks>The 'continuous query' model can be halted at any time by a call to this method.  A subsequent call to 'Run' will restart the continuous query.</remarks>
        public void Halt()
        {
            this.OnHalt(this, new EventArgs());
       }
    }
}
